package com.gdufe.user.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gdufe.common.feign.UaaFeign;
import com.gdufe.common.utils.R;
import com.gdufe.user.dto.LoginDto;
import com.gdufe.user.dto.PageUserDto;
import com.gdufe.user.dto.UserDto;
import com.gdufe.common.exception.ServiceException;
import com.gdufe.user.vo.LoginVo;
import com.gdufe.common.vo.PageBeanVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.gdufe.user.mapper.UserMapper;
import com.gdufe.common.entity.User;
import com.gdufe.user.service.UserAdminService;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.security.Principal;
import java.util.HashMap;
import java.util.Map;

@Service
public class UserAdminServiceImpl extends ServiceImpl<UserMapper, User> implements UserAdminService {

    @Autowired
    private UaaFeign uaaFeign;

    /**
     * 用户登录
     */
    @Override
    public LoginVo login(LoginDto loginDto) {
        //1.判断登录名称和密码是否为空
        if (StrUtil.isBlank(loginDto.getName()) || StrUtil.isBlank(loginDto.getPassword())) {
            throw new ServiceException(500, "数据输入不合法");
        }

        //2.判断登录姓名是否存在
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .eq(User::getName, loginDto.getName());
        User user = getOne(wrapper);
        if (user == null) {
            throw new ServiceException(500, "用户名或者密码错误");
        }

        //3.判断密码是否正确
        if (!new BCryptPasswordEncoder().matches(loginDto.getPassword(), user.getPassword())) {
            throw new ServiceException(500, "用户名或者密码错误");
        }

        //4.调用认证服务生成token
        Principal principal = (Principal) SecurityContextHolder.getContext().getAuthentication();
        Map<String, String> map = new HashMap<>();
        map.put("client_id", "web");
        map.put("client_secret", "123456");
        map.put("grant_type", "password");
        map.put("username", loginDto.getName());
        map.put("password", loginDto.getPassword());
        R r = uaaFeign.postAccessToken(principal, map);
        Map<String, String> data = (Map<String, String>) r.get("data");
        String token = data.get("access_token");

        //5.返回数据
        return LoginVo.builder()
                .name(user.getName())
                .token(token)
                .status(user.getStatus())
                .build();
    }


    /**
     * 用户注册
     *
     * @param userDto
     */
    @Override
    public void register(UserDto userDto) {
        //1.判断注册数据是否为空
        if (StrUtil.isBlank(userDto.getName()) || StrUtil.isBlank(userDto.getPassword())) {
            throw new ServiceException(500, "数据输入不合法");
        }

        //2.判断注册用户是否存在
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .eq(User::getName, userDto.getName());
        User user = getOne(wrapper);
        if (user != null) {
            throw new ServiceException(500, "用户已存在");
        }

        //3.插入数据
        user = new User();
        userDto.setPassword(new BCryptPasswordEncoder().encode(userDto.getPassword()));
        BeanUtil.copyProperties(userDto, user);
        user.setStatus(2);
        user.setLevel(0);
        user.setPoint(0);
        save(user);
    }


    /**
     * 修改用户信息
     *
     * @param userDto
     */
    @Override
    public void update(UserDto userDto) {
        User user = new User();
        BeanUtil.copyProperties(userDto, user);
        updateById(user);
    }

    /**
     * 条件分页查询
     *
     * @param pageUserDto
     * @return
     */
    @Override
    public PageBeanVo<User> pageQuery(PageUserDto pageUserDto) {
        //获取数据
        Integer page = pageUserDto.getPage();
        Integer pageSize = pageUserDto.getPageSize();
        Long id = pageUserDto.getId();
        String name = pageUserDto.getName();
        Integer level = pageUserDto.getLevel();

        //构建分页条件
        Page<User> p = Page.of(page, pageSize);

        //构建查询条件
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                //精确匹配
                .eq(id != null, User::getId, id)
                //模糊匹配
                .like(!StrUtil.isBlank(name), User::getName, name)
                .eq(level != null, User::getLevel, level)
                //只查询用户数据
                .eq(User::getStatus, 2);

        //查询
        page(p, wrapper);

        //封装数据返回
        return PageBeanVo.of(p.getTotal(), p.getRecords());
    }

    /**
     * 获取登录的用户信息
     *
     * @return
     */
    public User getAdminUser() {
        //获取当前线程的请求对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String authorization = request.getHeader("Authorization");
        String[] auth = authorization.split(" ");
        String token = auth[1];
        Long userId = null;
        if (!StrUtil.isBlank(token)) {
            userId = JWT.decode(token).getClaim("user_id").asLong();
        }
        return getById(userId);
    }

    /**
     * 根据姓名查询用户
     *
     * @param name
     * @return
     */
    @Override
    public User getUserByName(String name) {
        //构造查询条件
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .eq(User::getName, name);

        //查询数据并返回
        return getOne(wrapper);
    }
}